package com.dd.security.component;

import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;

import java.util.Collection;

/**
 * 权限判定管理器
 * 主要思路是判定用户所有角色列表中是否包含资源对应角色
 *
 */
@Slf4j
//@Component
public class MallAccessDecisionManager implements AccessDecisionManager {


    @Override
    public void decide(Authentication authentication, Object object,
                       Collection<ConfigAttribute> configAttributes)
            throws AccessDeniedException, InsufficientAuthenticationException {
        // 当前请求需要的权限
        log.info("collection:{}", configAttributes);
        // 当前用户所具有的权限,其中
        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
        log.info("principal:{} authorities:{}", authentication.getPrincipal().toString(), authorities);

        log.info("根据人员角色{}，资源要求角色{}进行匹配",authorities,configAttributes);

        for (ConfigAttribute configAttribute : configAttributes) {
            // 当前请求需要的权限
            String needRole = configAttribute.getAttribute();
            if ("ROLE_LOGIN".equals(needRole)) {
                if (authentication instanceof AnonymousAuthenticationToken) {
                    throw new BadCredentialsException("Not logged in!!");
                } else {

                    return;
                }
            }
            // 当前用户所具有的权限
            for (GrantedAuthority grantedAuthority : authorities) {
                // 包含其中一个角色即可访问
                if (grantedAuthority.getAuthority().equals(needRole)) {
                    log.info("角色匹配成功，用户有权限访问");
                    return;
                }
            }
        }
        throw new AccessDeniedException("您没有访问权限");
    }

    @Override
    public boolean supports(ConfigAttribute attribute) {
        return true;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return true;
    }
}
